//
//  MasterLiveViewController.swift
//  HinsLive
//
//  Created by haoxian on 2019/5/2.
//  Copyright © 2019 Hins. All rights reserved.
//

import UIKit
import LFLiveKit
import RxSwift
import SVProgressHUD


class MasterLiveViewController: LiveViewController {
    
    private var tips: UIAlertController?
    
    private lazy var session: LFLiveSession = {
        let session = LFLiveSession.default()
        session.delegate = self
        session.preView = view
        return session
    }()
    
    private(set) lazy var switchCameraBtn: RoomIconButton = {
        let btn = RoomIconButton(imageFrame: CGRect(x: 8, y: 8, width: 16, height: 16))
        btn.backgroundColor = .roomGrayBackgroundColor
        btn.layer.cornerRadius = 16
        btn.layer.masksToBounds = true
        btn.setImage(R.image.switch_camera(), for: .normal)
        btn.setImage(R.image.switch_camera(), for: .highlighted)
        return btn
    }()
    
    private var pickCoverView: LivePickCoverView?
    
    private var aliveTimer: Timer?
    
    private var feedItem: FeedItem?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupPrepareWork()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        session.running = true
        tips?.present()
        tips = nil
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        session.stopLive()
    }
}

private extension MasterLiveViewController {
    
    func setupPrepareWork() {
        tips = UIAlertController.alert(message: "拍摄或者选择一张照片作为直播间封面").addCancel(title: "我知道了")
        setPrepareToPick()
        dismissBtn.rx.tap.subscribe(onNext: { [weak self] _ in
            self?.view.endEditing(true)
            UIAlertController.alert(message: "确定要结束直播吗？")
                .addAction { _ in
                    self?.aliveTimer?.invalidate()
                    self?.aliveTimer = nil
                    self?.leaveAndDisconnet()
                    self?.safeDismiss()
                }
                .addCancel()
                .present()
        })
        .disposed(by: bag)
        view.bringSubviewToFront(dismissBtn)
        view.addSubview(switchCameraBtn)
        switchCameraBtn.snp.makeConstraints { (make) in
            make.size.centerY.equalTo(dismissBtn)
            make.right.equalTo(dismissBtn.snp.left).offset(-20)
        }
        switchCameraBtn.rx.tap.subscribe(onNext: { [weak self] _ in
            self?.switchCamera()
        }).disposed(by: bag)
    }
    
    func setPrepareToPick() {
        contentView.masterInfoView.isHidden = true
        contentView.messagesView.isHidden = true
        contentView.chatBtn.isHidden = true
        let pickCoverView = LivePickCoverView()
        self.pickCoverView = pickCoverView
        view.addSubview(pickCoverView)
        pickCoverView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        pickCoverView.albumBtn.rx.tap
            .flatMap(albumDidTap)
            .do(onNext: {[weak pickCoverView] _ in pickCoverView?.setDidPicked() })
            .bind(to: pickCoverView.coverImageView.rx.image)
            .disposed(by: bag)
        pickCoverView.takePhotoBtn.rx.tap
            .map { [weak self] in self?.session.currentImage }
            .do(onNext: {[weak pickCoverView] _ in pickCoverView?.setDidPicked() })
            .bind(to: pickCoverView.coverImageView.rx.image)
            .disposed(by: bag)
        pickCoverView.cancelBtn.rx.tap
            .subscribe(onNext: { [weak pickCoverView] _ in
                pickCoverView?.setPrepareToPick()
            })
            .disposed(by: bag)
        var req = LiveStartRequest.with {
            $0.uid = room.ruid
            $0.roomTitle = room.roomTitle
            $0.fid = room.fid
        }
        pickCoverView.doneBtn.rx.tap
            .do(onNext: { _ in SVProgressHUD.show() })
            .map { [weak pickCoverView] _ -> Data? in
                let image = pickCoverView?.coverImageView.image
                return image?.thumbnailImageData()
            }
            .unwrap()
            .map { data -> LiveStartRequest in
                req.imageData = data
                return req
            }
            .flatMap(Network.liveStart)
            .observeOn(MainScheduler.asyncInstance)
            .subscribe(onNext: { [weak self] feedItem in
                self?.feedItem = feedItem
                self?.setDidPicked()
                SVProgressHUD.dismiss()
            }) { [weak self] (error) in
                SVProgressHUD.dismiss()
                #if DEBUG
                self?.view.makeCenterMsg(error.localizedDescription)
                #else
                self?.view.makeCenterMsg("网络开小差啦~请重试~")
                #endif
            }
            .disposed(by: bag)
    }
    
    func setDidPicked() {
        pickCoverView?.removeFromSuperview()
        pickCoverView = nil
        contentView.masterInfoView.isHidden = false
        contentView.messagesView.isHidden = false
        contentView.chatBtn.isHidden = false
        startRunning()
        setupAliveTimer()
    }
    
    func startRunning() {
        let stream = LFLiveStreamInfo()
        stream.url = Network.rtmpHost + room.ruid;
        session.startLive(stream)
    }
    
    func setupAliveTimer() {
        guard let item = feedItem else { fatalError() }
        let timer = Timer(timeInterval: 25.0, repeats: true) { [weak self] _ in
            self?.socket.send(.alive, item)
        }
        RunLoop.current.add(timer, forMode: .common)
        aliveTimer = timer
    }
    
    func switchCamera() {
        if case .front = session.captureDevicePosition {
            session.captureDevicePosition = .back
        } else {
            session.captureDevicePosition = .front
        }
    }
}


private extension MasterLiveViewController {
    var albumDidTap: () -> Observable<UIImage?> {
        let o = UIImagePickerController.rx.create(self) { (imagePicker) in
                imagePicker.sourceType = .photoLibrary
            }
            .flatMap { $0.rx.didFinishPickingMediaWithInfo }
            .take(1)
            .map { $0[.originalImage] as? UIImage }
        return { o }
    }
}

extension MasterLiveViewController: LFLiveSessionDelegate {
    func liveSession(_ session: LFLiveSession?, errorCode: LFLiveSocketErrorCode) {
        switch errorCode {
        case .preView:
            view.makeCenterMsg("预览失败")
        case .getStreamInfo:
            view.makeCenterMsg("获取流媒体信息失败")
        case .connectSocket:
            view.makeCenterMsg("连接socket失败")
        case .verification:
            view.makeCenterMsg("验证服务器失败")
        case .reConnectTimeOut:
            view.makeCenterMsg("重新连接服务器超时")
        @unknown default:
            view.makeCenterMsg("未知错误")
        }
    }
}
